import Foundation

/// Represents the status of the motor operations.
enum MotorStatus {
    case ok      // Operation succeeded
    case timeout // Operation timed out
    case error   // An error occurred
}

/// Holds the parameters for motor configuration.
struct SerialMotorParameters {
    var isServo: Bool = false // If the motor is a servo TODO: 如果电机是伺服电机
    var acc: Int32 = 1200    // Acceleration value  TODO: 加速值
    var dcc: Int32 = 1200    // Deceleration value TODO: 减速值
    var speed: Int32 = 2400  // Speed value TODO: 速度值 移动距离
    var steps: Int32 = 0     // Number of steps for motor movement TODO: 电机移动的步数（单位：步）
    
    
   
}

/// Manages communication with serial motors using a serial port.
/// Provides methods to configure, control, and monitor motor status.
class SerialMotorManager {
    
    // MARK: - Properties
    
    var serialPortManager: SerialPortManager? // Handles serial port communication
    private var motorName: String?                   // Name of the motor device
    private var serialMotorParameters: [SerialMotorParameters] // Configuration for each motor channel
    
    private static var messageInterval: Double = 0 // Time between commands (seconds)
    private static var timeoutInterval: Double = 1.0   // Timeout for responses (seconds)
    private static var checkInterval: Double = 0.001   // Interval for checking motor status (seconds)
    private let isWaiting: Bool = true                 // Indicates if commands wait for responses
    
    // MARK: - Initialization
    
    /// Initializes a new SerialMotorManager instance.
    /// - Parameters:
    ///   - motorName: Name of the motor device.
    ///   - numChannels: Number of motor channels to manage (default: 255).
    init(motorName: String, baudRate: Int = 9600, numChannels: Int = 255) {
        self.motorName = motorName
        self.serialMotorParameters = Array(repeating: SerialMotorParameters(), count: numChannels)
        connectToMotor(motorName: motorName, baudRate: baudRate)
    }
    
    // MARK: - Connection Management
    
    /// Closes the serial port connection manually.
    func closeManually() {
        serialPortManager?.closeManually()
    }
    
    /// Checks if the motor is connected.
    /// - Returns: `true` if the motor is connected, `false` otherwise.
    func isConnected() -> Bool {
        return serialPortManager?.isSerialOpened() ?? false
    }
    
    /// Connects to the motor device using the specified name.
    /// - Parameter motorName: Name of the motor device.
    /// - Returns: `true` if the connection is successful, `false` otherwise.
    func connectToMotor(motorName: String, baudRate: Int = 9600) -> Bool {
        serialPortManager = SerialPortManager(baudRate: baudRate, isShowingMessage: true)
        serialPortManager?.openSerialDevice(serialName: motorName)
        return isConnected()
    }
    
    
    /// Sends the motor as a servo.
    /// - Parameter cmd: An array of bytes representing the command.
    /// - isServo: Whether the motor is a servo or not
    func setAsServo(channel: UInt8, isServo: Bool) {
        serialMotorParameters[Int(channel) - 1].isServo = isServo
    }
    
    // MARK: - Command Management
    
    /// Sends a command to the motor.
    /// - Parameter cmd: An array of bytes representing the command.
    private func sendCommand(cmd: [UInt8]) {//MARK: 这里是发送数据 给发电机
        serialPortManager?.sendUInt8(data: cmd)
        if (SerialMotorManager.messageInterval != 0) {
            Thread.sleep(forTimeInterval: SerialMotorManager.messageInterval)
        }
    }
    
    func stopMotor(channel: UInt8) -> MotorStatus {
        if (checkForEStop(channel: channel)) {
            return MotorStatus.error
        }
        var cmd: [UInt8] = [channel]
        cmd.append(0x06)
        cmd.append(0x00)
        cmd.append(0x7C)
        cmd.append(0x00)
        cmd.append(0xE2)
        
        
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 8, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            if (receivedBytes == nil) {
                return .timeout
            }
            return (receivedBytes!.elementsEqual(cmd)) ? .ok : .error
        }
        return .ok
    }
    
    func clearErrorCode(channel: UInt8) -> MotorStatus {
        if (checkForEStop(channel: channel)) {
            return MotorStatus.error
        }
        
        var cmd: [UInt8] = [channel]
        cmd.append(0x06)
        cmd.append(0x00)
        cmd.append(0x7C)
        cmd.append(0x00)
        cmd.append(0xBA)
        
        
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 8, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            if (receivedBytes == nil) {
                return .timeout
            }
            return (receivedBytes!.elementsEqual(cmd)) ? .ok : .error
        }
        return .ok
    }

    
    /// Enables the motor on a specific channel.
    /// - Parameter channel: Channel number (0–255).
    /// - Returns: Status of the operation (`ok`, `timeout`, `error`).
    func enableMotor(channel: UInt8) -> MotorStatus {
        if (checkForEStop(channel: channel)) {
            return MotorStatus.error
        }
        
        var cmd: [UInt8] = [channel]
        cmd.append(0x06)
        cmd.append(0x00)
        cmd.append(0x7C)
        cmd.append(0x00)
        cmd.append(0x9F)
        
        
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 8, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            if (receivedBytes == nil) {
                return .timeout
            }
            return (receivedBytes!.elementsEqual(cmd)) ? .ok : .error
        }
        return .ok
    }

    /// Disables the motor on a specific channel.
    /// - Parameter channel: Channel number (0–255).
    /// - Returns: Status of the operation (`ok`, `timeout`, `error`).
    func disableMotor(channel: UInt8) -> MotorStatus {
        if (checkForEStop(channel: channel)) {
            return MotorStatus.error
        }
        
        var cmd: [UInt8] = [channel]
        cmd.append(0x06)
        cmd.append(0x00)
        cmd.append(0x7C)
        cmd.append(0x00)
        cmd.append(0x9E)
    
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 8, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            if (receivedBytes == nil) {
                return .timeout
            }
            
            return (receivedBytes!.elementsEqual(cmd)) ? .ok : .error
            
        }
        return .ok
    }
    
    /// Checks if the motor on a specified channel has stopped.
    /// - Parameters:
    ///   - channel: The motor channel (UInt8).
    ///   - timeout: Time to wait for a response (Double, default 5 seconds).
    /// - Returns: `true` if the motor has stopped, `false` if it hasn’t, or `nil` if a timeout occurs.
    func isMotorStopped(channel: UInt8, timeout: Double = 5) -> Bool? {
        if (checkForEStop(channel: channel)) {
            return nil
        }
        var cmd: [UInt8] = [channel]
        cmd.append(0x03)
        cmd.append(0x00)
        
        if (serialMotorParameters[Int(channel) - 1].isServo) {
            cmd.append(0x02)
        } else {
            cmd.append(0x01)
        }
        
        cmd.append(0x00)
        
        if (serialMotorParameters[Int(channel) - 1].isServo) {
            cmd.append(0x02)
        } else {
            cmd.append(0x01)
        }
        
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            var bytesToReceive = 7
            if (serialMotorParameters[Int(channel) - 1].isServo) {
                bytesToReceive = 9
            }
            receivedBytes = getNBytes(numBytes: bytesToReceive, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            
            // If no response is received, return nil
            if (receivedBytes == nil) {
                return nil
            }
            
            return (receivedBytes![(serialMotorParameters[Int(channel) - 1].isServo) ? 6 : 4] == 0x09)
        }
        return false
    }
    
    /// Waits for the motor to stop within a specified timeout period.
    /// - Parameters:
    ///   - channel: The motor channel (UInt8).
    ///   - timeout: Maximum wait time (Double, default 5 seconds).
    /// - Returns: `.ok` if the motor stops, `.timeout` if timeout occurs, `.error` otherwise.
    func waitForStop(channel: UInt8, timeout: Double = 5) -> MotorStatus {
        
        let t1 = Date.now.timeIntervalSince1970
        var t2 = Date.now.timeIntervalSince1970
        if (isWaiting) {
            
            while ((t2 - t1) <= ( timeout * 1)) {
                var flag: Bool?
                
                flag = isMotorStopped(channel: channel, timeout: timeout)
                if (flag == nil) {
                    return .timeout
                }
                if (flag! ) {
                    return .ok
                }
                
                t2 = Date.now.timeIntervalSince1970
                
                Thread.sleep(forTimeInterval: TimeInterval(SerialMotorManager.checkInterval))
            }
            return .error
        }
        return .error
    }

    
    /// Moves the motor relatively using predefined steps.
    /// - Parameter channel: The motor channel (UInt8).
    /// - Returns: `.ok` if successful, `.error` otherwise.
    func relativelyMove(channel: UInt8) -> MotorStatus {
        if (checkForEStop(channel: channel)) {
            return MotorStatus.error
        }
        // 01 06 00 7C 00 66
        var cmd: [UInt8] = [channel]
        cmd.append(0x06)
        cmd.append(0x00)
        cmd.append(0x7C)
        cmd.append(0x00)
        cmd.append(0x66)
        
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 8, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            if (receivedBytes == nil) {
                return .timeout
            }
            
            return (receivedBytes!.elementsEqual(cmd)) ? .ok : .error
        }
        return .ok
    }

    /// Homes the motor to a specified position using a trigger value.
    /// - Parameters:
    ///   - channel: The motor channel (UInt8).
    ///   - trigger: Trigger value for homing (UInt8).
    /// - Returns: `.ok` if successful, `.error` otherwise.
    func homeMotor(channel: UInt8, trigger: UInt8) -> MotorStatus {
        if (checkForEStop(channel: channel)) {
            return MotorStatus.error
        }
        //01 10 00 7C 00 03 06 00 6E 00 31 00 4C 9D 67
        var cmd: [UInt8] = [channel]
        cmd.append(0x10)
        cmd.append(0x00)
        cmd.append(0x7C)
        cmd.append(0x00)
        cmd.append(0x03)
        cmd.append(0x06)
        cmd.append(0x00)
        cmd.append(0x6E)
        cmd.append(0x00)
        cmd.append(trigger)
        cmd.append(0x00)
        cmd.append(0x4C)
        
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 8, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            if (receivedBytes == nil) {
                return .timeout
            }
            var cmd_: [UInt8] = []
            for i in 0..<6 {
                cmd_.append(cmd[i])
            }
            let crc_ = calculateCRC16Modbus(input: cmd_)
            cmd_.append(crc_[0])
            cmd_.append(crc_[1])
            
            return (receivedBytes!.elementsEqual(cmd_)) ? .ok : .error
            
        }
        return .ok
    }

    
    /// Sets acceleration for the motor.
    /// - Parameters:
    ///   - channel: The motor channel (UInt8).
    ///   - acc: Acceleration value (Int32).
    /// - Returns: Motor status after applying the configuration.
    func setAcc(channel: UInt8, acc:Int32)-> MotorStatus {
        // 01 10 00 1B 00 05 0A 02 58 02 58 09 C4 00 07 A1 42
        self.serialMotorParameters[Int(channel) - 1].acc = acc
        return pushStepAndSpeed(channel: channel)
    }
    /// Sets deceleration for the motor.
    /// - Parameters:
    ///   - channel: The motor channel (UInt8).
    ///   - dcc: Deceleration value (Int32).
    /// - Returns: Motor status after applying the configuration.
    func setDcc(channel: UInt8, dcc:Int32)-> MotorStatus {
        // 01 10 00 1B 00 05 0A 02 58 02 58 09 C4 00 07 A1 42
        self.serialMotorParameters[Int(channel) - 1].dcc = dcc
        return pushStepAndSpeed(channel: channel)
    }
    /// Sets the number of steps for the motor.
    /// - Parameters:
    ///   - channel: The motor channel (UInt8).
    ///   - steps: Number of steps (Int32).
    /// - Returns: Motor status after applying the configuration.
    func setSteps(channel: UInt8, steps:Int32)-> MotorStatus {
        // 01 10 00 1B 00 05 0A 02 58 02 58 09 C4 00 07 A1 42
        self.serialMotorParameters[Int(channel) - 1].steps = steps
        return pushStepAndSpeed(channel: channel)
    }
    
    /// Sets the speed for the motor.
    /// - Parameters:
    ///   - channel: The motor channel (UInt8).
    ///   - speed: Speed value (Int32).
    /// - Returns: Motor status after applying the configuration.
    func setSpeed(channel: UInt8, speed:Int32) -> MotorStatus {
        // 01 10 00 1B 00 05 0A 02 58 02 58 09 C4 00 07 A1 42
        self.serialMotorParameters[Int(channel) - 1].speed = speed
        return pushStepAndSpeed(channel: channel)
    }
        
    /// Pushes step and speed parameters to the motor.
    /// - Parameter channel: The motor channel (UInt8).
    /// - Returns: `.ok` if successful, `.error` otherwise.
    func pushStepAndSpeed(channel: UInt8)  -> MotorStatus{
        if (checkForEStop(channel: channel)) {
            return MotorStatus.error
        }
        var cmd: [UInt8] = [channel]
        
            cmd.append(0x10)
        if (serialMotorParameters[Int(channel) - 1].isServo) {
            
            cmd.append(0x01)
            cmd.append(0x58)
            cmd.append(0x00)
            cmd.append(0x08)
            cmd.append(0x10)
            let _acc = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].acc)
            cmd.append(_acc[3])
            cmd.append(_acc[2])
            cmd.append(_acc[1])
            cmd.append(_acc[0])
            let _dcc = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].dcc)
            cmd.append(_dcc[3])
            cmd.append(_dcc[2])
            cmd.append(_dcc[1])
            cmd.append(_dcc[0])
            let _speed = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].speed)
            cmd.append(_speed[3])
            cmd.append(_speed[2])
            cmd.append(_speed[1])
            cmd.append(_speed[0])
            
            let _steps = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].steps)
            
            cmd.append(_steps[3])
            cmd.append(_steps[2])
            cmd.append(_steps[1])
            cmd.append(_steps[0])
        } else {
            cmd.append(0x00)
            cmd.append(0x1B)
            
            
            cmd.append(0x00)
            cmd.append(0x05)
            cmd.append(0x0A)
            
            let _acc = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].acc)
            cmd.append(_acc[1])
            cmd.append(_acc[0])
            let _dcc = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].dcc)
            cmd.append(_dcc[1])
            cmd.append(_dcc[0])
            let _speed = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].speed)
            cmd.append(_speed[1])
            cmd.append(_speed[0])
            
            let _steps = int32ToByteArray(value: serialMotorParameters[Int(channel) - 1].steps)
            
            cmd.append(_steps[3])
            cmd.append(_steps[2])
            cmd.append(_steps[1])
            cmd.append(_steps[0])
        }
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        self.sendCommand(cmd: cmd)
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 8, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            if (receivedBytes == nil) {
                return .timeout
            }
            
            
            var cmd_: [UInt8] = []
            for i in 0..<6 {
                cmd_.append(cmd[i])
            }
            let crc_ = calculateCRC16Modbus(input: cmd_)
            cmd_.append(crc_[0])
            cmd_.append(crc_[1])
            
            
            return (receivedBytes!.elementsEqual(cmd_)) ? .ok : .error
            
        }
        return .ok
    }
    // Retrieves the position of the motor for the given channel.
    // Sends a command to query the motor's position and processes the response.
    // Returns the position as an Int32 value if successful, or nil if there's an error or timeout.
    func getPosition(channel: UInt8) -> Int32? {
        if (checkForEStop(channel: channel)) {
            return nil
        }
        // Command to retrieve position: 03 00 06 00 02
        var cmd: [UInt8] = [channel]
        cmd.append(0x03) // Function code to read data
        cmd.append(0x00) // Starting address
        cmd.append(0x06)
        cmd.append(0x00)
        cmd.append(0x02) // Number of bytes to request
        
        // Calculate CRC16 Modbus checksum for the command
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        // Send the command via serial communication
        self.sendCommand(cmd: cmd)
        
        // Check if the system is waiting for a response
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            receivedBytes = getNBytes(numBytes: 9, timeout: 10, checkInterval: SerialMotorManager.checkInterval)
            
            // If no response is received, return nil
            if (receivedBytes == nil) {
                return nil
            }
            
            // If the response contains 9 bytes, validate the CRC and extract the position
            if (receivedBytes!.count == 9) {
                let crc_ = calculateCRC16Modbus(input: Array(receivedBytes![0..<7]))
                // Check if the response's CRC is valid
                if (Array(receivedBytes![7..<9]).elementsEqual(crc_)) {
                    // Return the position as an Int32 value by converting the bytes
                    return byteArrayToInt32(bytes: Array(receivedBytes![3..<7]))
                }
            }
        }
        return nil
    }
    
    func checkForEStop(channel: UInt8) -> Bool {
        if (serialMotorParameters[Int(channel) - 1].isServo) {
            return false
        }
        var cmd: [UInt8] = [channel]
        cmd.append(0x03) // Function code to read data
        cmd.append(0x00) // Starting address
        cmd.append(0x03)
        cmd.append(0x00)
            cmd.append(0x01)
        
        
        
        // Calculate CRC16 Modbus checksum for the command
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        // Send the command via serial communication
        self.sendCommand(cmd: cmd)
        
        // Check if the system is waiting for a response
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            var bytesToReceive = 7
            receivedBytes = getNBytes(numBytes: bytesToReceive, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            
            // If no response is received, return nil
            if (receivedBytes == nil) {
                return false
            }
            
            // If the response contains 8 bytes, validate the CRC and extract the error code
            if (receivedBytes!.count == bytesToReceive) {
                return (receivedBytes![4] & 0x10 == 0x10)
            }
        }
        return false
    }

    // Retrieves the error code for the motor at the given channel.
    // Sends a command to query the motor's error status and processes the response.
    // Returns an array of error codes if present, or nil if there's an error or timeout.
    func getErrorCode(channel: UInt8) -> [UInt8]? {
        
            if (checkForEStop(channel: channel)) {
                return nil
            }
        var errorCode: [UInt8] = []
        var cmd: [UInt8] = [channel]
        cmd.append(0x03) // Function code to read data
        cmd.append(0x00) // Starting address
        cmd.append(0x00)
        cmd.append(0x00)
        if (serialMotorParameters[Int(channel) - 1].isServo) {
            cmd.append(0x02)
        } else {
            cmd.append(0x01)
        }
        
        
        // Calculate CRC16 Modbus checksum for the command
        let crc = calculateCRC16Modbus(input: cmd)
        cmd.append(crc[0])
        cmd.append(crc[1])
        
        // Send the command via serial communication
        self.sendCommand(cmd: cmd)
        
        // Check if the system is waiting for a response
        if (isWaiting) {
            var receivedBytes: [UInt8]?
            var bytesToReceive = 7
            if (serialMotorParameters[Int(channel) - 1].isServo) {
                bytesToReceive = 9
            }
            receivedBytes = getNBytes(numBytes: bytesToReceive, timeout: SerialMotorManager.timeoutInterval, checkInterval: SerialMotorManager.checkInterval)
            
            // If no response is received, return nil
            if (receivedBytes == nil) {
                return nil
            }
            
            // If the response contains 7 bytes, validate the CRC and extract the error code
            if (receivedBytes!.count == bytesToReceive) {
                let crc_ = calculateCRC16Modbus(input: Array(receivedBytes![0..<(bytesToReceive - 2)]))
                // Check if the response's CRC is valid
                if (Array(receivedBytes![(bytesToReceive - 2)..<bytesToReceive]).elementsEqual(crc_)) {
                    // Append the error code bytes to the errorCode array
                    for i in 3..<(bytesToReceive - 2) {
                        errorCode.append(receivedBytes![i])
                    }
                    return errorCode
                }
            }
        }
        return nil
    }

    // Retrieves a specific number of bytes from the serial port.
    // Waits for the specified timeout duration and checks for incoming data at the defined interval.
    // Returns the received bytes if successful, or nil if there's a timeout or error.
    func getNBytes(numBytes: Int, timeout: Double, checkInterval: Double, isShowingResponse: Bool = true) -> [UInt8]? {
        let t1 = Date.now.timeIntervalSince1970
        
        var receivedBytes: [UInt8] = []
        
        // Continuously check for received data until the specified number of bytes is received
        while((receivedBytes.count) < numBytes) {
            
            // Wait for the next check interval before checking again
            Thread.sleep(forTimeInterval: TimeInterval(checkInterval))
            receivedBytes = (self.serialPortManager?.getInstantReceivedData())!
            
            if (receivedBytes.count == numBytes) {
                break
            }
            
            // If stop reading flag is set, clear received data and return nil
            if (serialPortManager!.stopReading) {
                serialPortManager?.clearInstantReceivedData()
                return nil
            }
            
            let t2 = Date.now.timeIntervalSince1970
            // If the timeout duration is exceeded, return nil
            if ((t2 - t1) > timeout) {
                serialPortManager?.clearInstantReceivedData()
                return nil
            }
        }
        
        // Slice the received data to the required number of bytes
        receivedBytes = Array(receivedBytes[0..<numBytes])
        
        if (isShowingResponse) {
            // Log the received bytes if needed
            let hexString = receivedBytes.map { String(format: "%02X", $0) }.joined(separator: " ")
           }
        
        // Clear received data after processing
        serialPortManager?.clearInstantReceivedData()
        
        return receivedBytes
    }

}
